<?php


namespace app\command\count;


use app\common\model\ContentReadModel;
use app\common\model\CountArticle;
use app\common\model\MoneyRecordModel;
use org\DingDingRobot;
use think\console\Command;
use think\console\Output;
use think\console\Input;
use think\console\input\Argument;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

/**
 * 文章统计脚本  此任务依赖于 sys_content_read表,需等sys_content_read表数据更新后再执行
 * Class CountArticleCommand
 * @package app\command\count
 */
class CountArticleCommand extends Command
{
    protected function configure()
    {
        $this->setName('count_article')
            ->addArgument('begin_day', Argument::OPTIONAL, '指定执行开始日期')
            ->addArgument('end_day', Argument::OPTIONAL, '指定执行截至日期')
            ->setDescription('文章统计脚本');
    }

    /**
     * @param Input $input
     * @param Output $output
     * @return int|void|null
     */
    protected function execute(Input $input, Output $output)
    {
        $begin_day = $input->getArgument('begin_day');
        $end_day   = $input->getArgument('end_day');

        if (empty($end_day) && empty($begin_day)) {

            # 定时任务配置在凌晨之后，默认跑前一天的数据
            $date = date('Y-m-d', strtotime(date('Y-m-d') . ' -1 day'));
            $this->buildData($date, $output);

        } elseif (!empty($begin_day) && !empty($end_day)) {

            # 跑指定日期范围的数据
            $begin_time = strtotime(date('Y-m-d 00:00:00', strtotime($begin_day)));
            $end_time   = strtotime(date('Y-m-d 23:59:59', strtotime($end_day)));

            for ($i = $begin_time; $i < $end_time; $i += 86400) {
                $date = date('Y-m-d', $i);
                $this->buildData($date, $output);
                $output->info($date);
            }

        } elseif (!empty($begin_day)) {
            # 跑指定日期的数据
            $date = date('Y-m-d', strtotime($begin_day));
            $this->buildData($date, $output);
            $output->info($date);
        }
    }

    /**
     * 文章统计
     * 日期    阅读人数    奖励人数    金币总数    1次    2次    3次    4次    5次    6次    7次    8次    9次    10次    10次以上
     * 阅读人数：指当天有多少人看过新闻，进入新闻页即算1人
     * 奖励人数：指当天一共有多少人拿过阅读奖励
     * 金币总数：指当天共发放的阅读奖励金币总数
     * 后面的次数：拿1次、2次、10次的分别有多少人
     * @param string $date
     * @param Output $output
     */
    protected function buildData(string $date, Output $output)
    {

        try {
            // 阅读人数
            $read_data = ContentReadModel::where("write_date", $date)->field("count(DISTINCT member_id) read_num")->find();

            $model      = MoneyRecordModel::where([
                ['write_date', '=', $date],
                ['method', 'IN', [4, 16]], // 4=阅读文章  6=阅读任务
            ]);
            $field      = [
                "count(DISTINCT member_id) award_num", // 奖励人数：指当天一共有多少人拿过阅读奖励
                "sum(amount) gold_num", // 金币总数：指当天共发放的阅读奖励金币总数
            ];

            $award_data = $model->field($field)->find();

            # 后面的次数：拿1次、2次、10次的分别有多少人
            $group_user = $model->group("member_id")->column("count(id) num", "member_id");
            $user_count = [];
            foreach ($group_user as $key => $val) {
                if ($val > 10) {
                    $user_count['10_more'] = ($user_count['10_more'] ?? 0) + 1;   // 10次以上的
                } else {
                    $user_count[$val] = ($user_count[$val] ?? 0) + 1;   // 次数 => 用户数
                }
            }

            $data = [
                'record_date' => $date,
                'read_num'    => $read_data['read_num'] ?? 0,
                'award_num'   => $award_data['award_num'] ?? 0,
                'gold_num'    => $award_data['gold_num'] ?? 0,
                'num_1'       => $user_count[1] ?? 0,
                'num_2'       => $user_count[2] ?? 0,
                'num_3'       => $user_count[3] ?? 0,
                'num_4'       => $user_count[4] ?? 0,
                'num_5'       => $user_count[5] ?? 0,
                'num_6'       => $user_count[6] ?? 0,
                'num_7'       => $user_count[7] ?? 0,
                'num_8'       => $user_count[8] ?? 0,
                'num_9'       => $user_count[9] ?? 0,
                'num_10'      => $user_count[10] ?? 0,
                'num_10_more' => $user_count["10_more"] ?? 0,
                'create_time' => time(),
            ];

            $row = CountArticle::where("record_date", $date)->find();
            if ($row) {
                CountArticle::update($data, ['id' => $row['id']]);
            } else {
                CountArticle::insert($data);
            }

            DingDingRobot::getInstance()->pushText("文章统计脚本,执行完成,日期:{$date}");
        } catch (DataNotFoundException $e) {
            DingDingRobot::getInstance()->pushText("文章统计脚本异常，日期:{$date},内容：" . $e->getMessage());
        } catch (ModelNotFoundException $e) {
            DingDingRobot::getInstance()->pushText("文章统计脚本异常，日期:{$date},内容：" . $e->getMessage());
        } catch (DbException $e) {
            DingDingRobot::getInstance()->pushText("文章统计脚本异常，日期:{$date},内容：" . $e->getMessage());
        }
    }
}